package com.hejx;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by 追风少年
 * 名词解释:
 *      刻子: 刻子是麻将的基础术语之一，意为三张同样的牌构成的牌型组合。
 *      将牌: 麻将的一般胡牌牌型是四个副（顺子或刻子）、一个对。这个对就叫做“将牌”
 * @email doubihah@foxmail.com
 * @create 2017-07-13 9:41
 **/
public class Majiang {

    // 数字 {01 ~ 09} 表示  {1 ~ 9} 筒
    // 数字 {11 ~ 19} 表示  {1 ~ 9} 条
    // 数字 {21 ~ 29} 表示  {1 ~ 9} 万
    private static Integer[] all_pai = {
            1,2,3,4,5,6,7,8,9,
            11,12,13,14,15,16,17,18,19,
            21,22,23,24,25,26,27,28,29
    };


    /**
     * 判断是否胡牌
     * @param mah 玩家手牌
     * @param id 得到的牌
     * @return
     */
    public static boolean canHu(List<Integer> mah, int id){
        ArrayList<Integer> pais = new ArrayList<Integer>(mah); // 克隆一个手牌列表
        pais.add(id);   // 加入手牌进行判断 是否胡牌了
        if(pais.size() == 2){ // 只有两张牌
            return pais.get(0) == pais.get(1);
        }
        Collections.sort(pais); // 升序排序,方便后面逻辑处理
        for (int i = 0; i < pais.size(); i++){// 依据牌的顺序从左到右依次分出将牌
            ArrayList<Integer> pais2 = new ArrayList<Integer>(pais); // 克隆一个手牌列表
            int count = 0;
            for (Integer pai : pais2) {
                if(pai == pais.get(i)){
                    count++;
                }
            }// for pais2
            if(count > 1){ // 移除将牌
                pais2.remove(pais.get(i));
                pais2.remove(pais.get(i));
                i += count; // 避免重复运算 将光标移到其他牌上
                if (huPanDin(pais2)) return true;
            }
        }
        return false;
    }

    /**
     * 胡牌判定
     * @return
     */
    private static boolean huPanDin(List<Integer> mah_list){
        if (mah_list.size() == 0) return true;
        Integer first = mah_list.get(0);
        if (mah_list.size() < 3) return false;
        if(first == mah_list.get(1) && first == mah_list.get(2) ){ // 尝试组成刻子
            mah_list.remove(first);
            mah_list.remove(first);
            mah_list.remove(first);
            return huPanDin(mah_list);
        }else{ // 尝试组成顺子
            Integer mah2 = first + 1;
            Integer mah3 = first + 2;
            if(mah_list.contains(mah2) && mah_list.contains(mah3)){
                mah_list.remove(first);
                mah_list.remove(mah2);
                mah_list.remove(mah3);
                return huPanDin(mah_list);
            }
        }
        return false;
    }

    /**
     * 获取所有的听牌
     * @param mahs 手牌
     */
    public static List<Integer> getTingPaiList(List<Integer> mahs){
        List<Integer> tings = new ArrayList<Integer>();
        for (Integer mah : all_pai) {
            if (canHu(mahs,mah)) tings.add(mah);
        }
        return tings;
    }

}
